package com.zyplayer.dubbo.service;

import com.zyplayer.doc.annotation.DocParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ClassLoadService {
	private static Logger logger = LoggerFactory.getLogger(ClassLoadService.class);
	
	public static void main(String[] args) throws Exception {
		URL urlJar = new URL("jar:file:/D:\\maven\\repository\\com\\zyplayer\\dubbo-api\\1.0\\dubbo-api-1.0.jar!/");
		JarFile jar = ((JarURLConnection) urlJar.openConnection()).getJarFile();
		JarEntry jarEntry = jar.getJarEntry("com/zyplayer/dubbo/service/AnnotateService.class");
		if (jarEntry == null) {
			logger.info("未找到类");
			return;
		}
//		Set<Class<?>> list = new LinkedHashSet<>();
//		findClassesByJar("", jar, list);
//		String name = jarEntry.getName();
		
		URL urlFile = new URL("file:D:\\maven\\repository\\com\\zyplayer\\dubbo-api\\1.0\\dubbo-api-1.0.jar");
		URLClassLoader myClassLoader = new URLClassLoader(new URL[] { urlFile }, Thread.currentThread().getContextClassLoader());
		Class<?> clazz = myClassLoader.loadClass("com.zyplayer.dubbo.service.AnnotateService");
		Method[] methods = clazz.getMethods();
		for (Method method : methods) {
			DocParam annotation1 = method.getAnnotation(DocParam.class);
			if (annotation1 != null) {
				logger.info("");
			}
			
			String methodName = method.getName();
			String resultType = method.getGenericReturnType().getTypeName();
			Type[] parameterTypes = method.getGenericParameterTypes();
			Parameter[] parameters = method.getParameters();
			for (int i = 0; i < parameterTypes.length; i++) {
			}
			logger.info("methodName:{},resultType:{}", methodName, resultType);
		}
	}
	
	
	private static void findClassesByJar(String pkgName, JarFile jar, Set<Class<?>> classes) {
		String pkgDir = pkgName.replace(".", "/");
		// 从此jar包 得到一个枚举类
		Enumeration<JarEntry> entry = jar.entries();
		JarEntry jarEntry;
		String name, className;
		Class<?> claze;
		// 同样的进行循环迭代
		while (entry.hasMoreElements()) {
			// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文
			jarEntry = entry.nextElement();
			name = jarEntry.getName();
			// 如果是以/开头的
			if (name.charAt(0) == '/') {
				// 获取后面的字符串
				name = name.substring(1);
			}
			if (jarEntry.isDirectory() || !name.startsWith(pkgDir) || !name.endsWith(".class")) {
				continue;
			}
			//如果是一个.class文件 而且不是目录
			// 去掉后面的".class" 获取真正的类名
			className = name.substring(0, name.length() - 6);
			//加载类
			claze = loadClass(className.replace("/", "."));
			// 添加到集合中去
			if (claze != null) {
				classes.add(claze);
			}
		}
	}
	
	/**
	 * 加载类
	 *
	 * @param fullClzName 类全名
	 * @return
	 */
	private static Class<?> loadClass(String fullClzName) {
		try {
			return Thread.currentThread().getContextClassLoader().loadClass(fullClzName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
}
